iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 17
0
Modern Web

Go into Web!系列 第 17

Day 17 | 使用 golang 與 MongoDB 互動

  • 分享至 

  • xImage
  •  

昨天講完 NoSQL 的概念並且將 MongoDB 安裝完成,今天就讓我們使用 golang 來存取 MongoDB 吧!

Mgo

mgo 是一款好用的 MongoDB Driver,他將許多方法進行封裝讓使用者可以更快速地上手,

安裝

透過 go get 的方式進行安裝

go get gopkg.in/mgo.v2

連線

在一切開始之前,我們先透過 Dial 方法連線至 MongoDB

session, err := mgo.Dial("127.0.0.1:27017")
if err != nil {
    panic(err)
}

驗證身份

如果有設定帳號密碼驗證,新增一個 Credential 後,透過 Login 方法進行登入

cred := &mgo.Credential{
    Username: username,
    Password: password,
}
err := session.Login(cred)
if err != nil {
    panic(err)
}

選擇 Database 與 Collection

今天以 登入紀錄 為範例,因此我們資料庫選擇為 user,而 Collection 選擇使用 user.info,以下透過 mgo 進行

db := session.DB("user")
c := db.C("login.info")

資料

資料設計

假設今天我們要存放的是登入的資訊,我們可以設計一個 struct 如下,分別紀錄使用者id、ip、登入狀態與登入時間

type LoginInfo struct {
	UserID     int64     `json:"userId"`
	ClientIP   string    `json:"clientIP"`
	LoginState string    `json:"loginState"`
	LoginTime  time.Time `json:"loginTime"`
}

資料建立

我們設計一個方法快速的建立 LoginInfo 的 instance 如下

func NewLoginInfo(id int64, clientIP string, loginState string) *LoginInfo{
	return &LoginInfo{
		UserID: id,
		ClientIP: clientIP,
		LoginState: loginState,
		LoginTime: time.Now(),
	}
}

新增

透過 Insert 方法可以直接將 document 新增至 MongoDB 中如下

err = c.Insert(NewLoginInfo(1234, "127.0.0.1", "success"))
if err != nil {
    panic(err)
}

驗證

目前整體程式如下

package main

import (
	"fmt"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
	"time"
)

type LoginInfo struct {
	UserID     int64     `json:"userId"`
	ClientIP   string    `json:"clientIP"`
	LoginState string    `json:"loginState"`
	LoginTime  time.Time `json:"loginTime"`
}

func main() {
	session, err := mgo.Dial("127.0.0.1:27017")
	if err != nil {
		panic(err)
	}
	db := session.DB("user")
	c := db.C("login.info")
	err = c.Insert(NewLoginInfo(1234, "127.0.0.1", "success"))
	if err != nil {
		panic(err)
	}
}

func NewLoginInfo(id int64, clientIP string, loginState string) *LoginInfo{
	return &LoginInfo{
		UserID: id,
		ClientIP: clientIP,
		LoginState: loginState,
		LoginTime: time.Now(),
	}
}

將程式執行完畢後,可以透過昨天提到的 compass 來查看 MongoDB 內的資料,如果查詢 user 內的 login.info 可以查訊到相關資料代表程式執行成功

查詢

批次查詢

查詢的部分就更簡單拉,可以透過 Find 方法進行查詢後,透過 All 方法將結果 mapping 到物件內,以下為查詢 userid1234 的範例

var loginHistory []LoginInfo
err = c.Find(bson.M{"userid": 1234}).All(&loginHistory)
if err != nil {
    panic(err)
}
for _, history := range loginHistory {
    fmt.Println(history)
}

單次查詢與排序

在查詢登入紀錄時,可能會有 查詢最後一次登入 的需求出現,這時我們就可以使用 Sort 來排序我們想要排序的欄位,欄位名稱前面加入 - 代表倒序,最後使用 One 方法抓取一筆資料,以下為範例

var lastLogin LoginInfo
err = c.Find(bson.M{"userid": 1234}).Sort("-logintime").One(&lastLogin)
if err != nil {
    panic(err)
}
fmt.Println(lastLogin)

最終程式結果

今天的範例程式全部如下

package main

import (
	"fmt"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
	"time"
)

type LoginInfo struct {
	UserID     int64     `json:"userId"`
	ClientIP   string    `json:"clientIP"`
	LoginState string    `json:"loginState"`
	LoginTime  time.Time `json:"loginTime"`
}

func main() {
	session, err := mgo.Dial("127.0.0.1:27017")
	if err != nil {
		panic(err)
	}
	db := session.DB("user")
	c := db.C("login.info")
	err = c.Insert(NewLoginInfo(1234, "127.0.0.1", "success"))
	if err != nil {
		panic(err)
	}

	var loginHistory []LoginInfo
	err = c.Find(bson.M{"userid": 1234}).All(&loginHistory)
	for _, history := range loginHistory {
		fmt.Println(history)
	}

	fmt.Println("==========================")

	var lastLogin LoginInfo
	err = c.Find(bson.M{"userid": 1234}).Sort("-logintime").One(&lastLogin)
	if err != nil {
		panic(err)
	}
	fmt.Println(lastLogin)

}

func NewLoginInfo(id int64, clientIP string, loginState string) *LoginInfo{
	return &LoginInfo{
		UserID: id,
		ClientIP: clientIP,
		LoginState: loginState,
		LoginTime: time.Now(),
	}
}

多跑幾次,結果如果沒有爆出錯誤就代表執行成功拉!

{1234 127.0.0.1 success 2020-09-17 22:59:15.593 +0800 CST}
{1234 127.0.0.1 success 2020-09-17 22:59:49.278 +0800 CST}
{1234 127.0.0.1 success 2020-09-17 22:59:51.175 +0800 CST}
{1234 127.0.0.1 success 2020-09-17 23:02:32.815 +0800 CST}
{1234 127.0.0.1 success 2020-09-17 23:02:50.345 +0800 CST}
==========================
{1234 127.0.0.1 success 2020-09-17 23:02:50.345 +0800 CST}

小結

最近剛好有專案需要用到 MongoDB,因此就使用 mgo 這個 package 來實作,希望可以幫到需要的朋友!

參考資料


上一篇
Day 16 | MongoDB - 好用的 NoSQL 資料庫
下一篇
Day18 | WebSocket - 神奇的雙向溝通協定
系列文
Go into Web!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
zhijiun
iT邦新手 4 級 ‧ 2022-12-15 00:25:53

你好,我一直出現 panic: no reachable servers 、exit status 2 的字樣,然後連不上 mongodb,請問可以怎麼解決?

我要留言

立即登入留言